package io.shuttle.mbe.api

import io.shuttle.mbe.api.annotation.ChromeMinVersion
import io.shuttle.mbe.api.types.Value1Function

////////////////////
// Proxy
////////////////////
/**
 * Use the `Browser.proxy` API to manage Chrome's proxy settings. This API relies on the ChromeSetting prototype of the type API for getting and setting the proxy configuration.
 *
 * Permissions: "proxy"
 */
interface Proxy {
    val settings: ChromeSetting<ProxyConfig>

    val onProxyError: Events.Event<Value1Function<ProxyError>>

    @ChromeMinVersion(54)
    enum class Mode {
        direct,
        auto_detect,
        pac_script,
        fixed_servers,
        system,
    }

    // An object holding proxy auto-config information. Exactly one of the fields should be non-empty.
    data class PacScript(
        // A PAC script.
        var data: String?,
        // If true, an invalid PAC script will prevent the network stack from falling back to direct connections. Defaults to false.
        var mandatory: Boolean?,
        // URL of the PAC file to be used.
        var url: String?,
    )

    // An object encapsulating a complete proxy configuration.
    data class ProxyConfig(
        // 'direct' = Never use a proxy 'auto_detect' = Auto detect proxy settings 'pac_script' = Use specified PAC script 'fixed_servers' = Manually specify proxy servers 'system' = Use system proxy settings
        var mode: Mode,
        // The proxy auto-config (PAC) script for this configuration. Use this for 'pac_script' mode.
        var pacScript: PacScript?,
        // The proxy rules describing this configuration. Use this for 'fixed_servers' mode.
        var rules: ProxyRules?,
    )

    // An object encapsulating the set of proxy rules for all protocols. Use either 'singleProxy' or (a subset of) 'proxyForHttp', 'proxyForHttps', 'proxyForFtp' and 'fallbackProxy'.
    data class ProxyRules(
        // List of servers to connect to without a proxy server.
        var bypassList: List<String>?,
        // The proxy server to be used for everthing else or if any of the specific proxyFor... is not specified.
        var fallbackProxy: ProxyServer?,
        // The proxy server to be used for FTP requests.
        var proxyForFtp: ProxyServer?,
        // The proxy server to be used for HTTP requests.
        var proxyForHttp: ProxyServer?,
        // The proxy server to be used for HTTPS requests.
        var proxyForHttps: ProxyServer?,
        // The proxy server to be used for all per-URL requests (that is http, https, and ftp).
        var singleProxy: ProxyServer?,
    )

    // An object encapsulating a single proxy server's specification.
    data class ProxyServer(
        // The hostname or IP address of the proxy server. Hostnames must be in ASCII (in Punycode format). IDNA is not supported, yet.
        var host: String,
        // The port of the proxy server. Defaults to a port that depends on the scheme.
        var port: Number?,
        // The scheme (protocol) of the proxy server itself. Defaults to 'http'.
        var scheme: Scheme?,
    )

    @ChromeMinVersion(54)
    enum class Scheme {
        http,
        https,
        quic,
        socks4,
        socks5
    }

    data class ProxyError(
        // Additional details about the error such as a JavaScript runtime error.
        var details: String,
        // The error description.
        var error: String,
        // If true, the error was fatal and the network transaction was aborted. Otherwise, a direct connection is used instead.
        var fatal: Boolean,
    )
}